package com.usooft.metaTalent.core.system.service.base;

import com.usooft.framework.core.query.Limit;
import com.usooft.framework.core.query.Page;
import com.usooft.metaTalent.core.system.entity.Employee;
import com.usooft.metaTalent.core.system.entity.EmployeeWxOpenUser;
import com.usooft.metaTalent.core.system.mapper.EmployeeWxOpenUserMapper;
import com.usooft.metaTalent.core.system.query.EmployeeWxOpenUserQuery;
import com.usooft.metaTalent.core.system.service.EmployeeWxOpenUserService;
import com.usooft.metaTalent.core.system.wrapper.EmployeeWxOpenUserWrapper;
import java.lang.Long;
import java.lang.Override;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.lang.NonNull;

public abstract class BaseEmployeeWxOpenUserService implements EmployeeWxOpenUserService {
    @Autowired
    private EmployeeWxOpenUserMapper employeeWxOpenUserMapper;

    @Override
    public EmployeeWxOpenUser get(@NonNull Long id) {
        return find(id).orElseThrow();
    }

    @Override
    public Optional<EmployeeWxOpenUser> find(@NonNull Long id) {
        return Optional.ofNullable(employeeWxOpenUserMapper.get(id));
    }

    @Override
    public List<EmployeeWxOpenUserWrapper> list(EmployeeWxOpenUserQuery query) {
        return employeeWxOpenUserMapper.list(query);
    }

    @Override
    public Page<EmployeeWxOpenUserWrapper> page(EmployeeWxOpenUserQuery query) {
        int rows = employeeWxOpenUserMapper.count(query.getFilter());
        return new Page<>(rows, rows == 0 ? new ArrayList<>() : employeeWxOpenUserMapper.list(query));
    }

    protected Optional<EmployeeWxOpenUser> findOne(EmployeeWxOpenUserQuery.Filter filter,
            EmployeeWxOpenUserQuery.Sorts sorts) {
        List<EmployeeWxOpenUserWrapper> wrappers = list(EmployeeWxOpenUserQuery.builder()
                                .filter(filter)
                                .sorts(sorts)
                                .limit(Limit.rowCount(1))
                                .build());
        return wrappers.stream().findFirst().map(Function.identity());
    }

    protected Optional<EmployeeWxOpenUser> findOne(EmployeeWxOpenUserQuery.Filter filter) {
        return findOne(filter, EmployeeWxOpenUserQuery.Sorts.builder().build());
    }

    @Override
    public int count(EmployeeWxOpenUserQuery.Filter filter) {
        return employeeWxOpenUserMapper.count(filter);
    }

    protected EmployeeWxOpenUser internalAdd(Employee employee, Long wxOpenUserId) {
        EmployeeWxOpenUser employeeWxOpenUser = new EmployeeWxOpenUser();
        employeeWxOpenUser.setEmployeeId(Optional.ofNullable(employee).map(Employee::getId).orElse(null));
        employeeWxOpenUser.setWxOpenUserId(wxOpenUserId);

        employeeWxOpenUser.setCreatedDate(LocalDateTime.now());
        employeeWxOpenUser.setVersion(0);
        employeeWxOpenUserMapper.add(employeeWxOpenUser);
        return employeeWxOpenUser;
    }

    protected void internalUpdate(@NonNull EmployeeWxOpenUser employeeWxOpenUser) {
        employeeWxOpenUser.setLastModifiedDate(LocalDateTime.now());

        int rows = employeeWxOpenUserMapper.update(employeeWxOpenUser);
        if (rows == 0) {
            throw new OptimisticLockingFailureException("更新失败。可能员工关联微信开放平台用户 (" + employeeWxOpenUser.getId() + ") 的版本 (" + employeeWxOpenUser.getVersion() + ") 已不是最新");
        }
        employeeWxOpenUser.setVersion(employeeWxOpenUser.getVersion() + 1);
    }

    protected void internalDelete(@NonNull EmployeeWxOpenUser employeeWxOpenUser) {
        int rows = employeeWxOpenUserMapper.delete(employeeWxOpenUser);
        if (rows == 0) {
            throw new OptimisticLockingFailureException("删除失败。可能员工关联微信开放平台用户 (" + employeeWxOpenUser.getId() + ") 的版本 (" + employeeWxOpenUser.getVersion() + ") 已不是最新");
        }
    }
}
